package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
)

// QRCodeHandler 处理二维码请求
func QRCodeHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	qq := vars["qq"]

	if qq == "" {
		http.Error(w, "QQ号不能为空", http.StatusBadRequest)
		return
	}

	// 构建二维码文件路径
	qrcodePath := filepath.Join(qq, "cache", "qrcode.png")

	// 检查文件是否存在
	if _, err := os.Stat(qrcodePath); os.IsNotExist(err) {
		http.Error(w, "二维码不存在", http.StatusNotFound)
		return
	}

	// 检查请求是否来自浏览器（通过Accept头判断）
	accept := r.Header.Get("Accept")
	if strings.Contains(accept, "text/html") {
		// 返回HTML页面，包含自动刷新功能
		renderQRCodePage(w, qq)
		return
	}

	// 直接返回图片文件
	http.ServeFile(w, r, qrcodePath)
}

// QRCodeInfoHandler 返回二维码文件信息的API接口
func QRCodeInfoHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	qq := vars["qq"]

	if qq == "" {
		http.Error(w, "QQ号不能为空", http.StatusBadRequest)
		return
	}

	// 构建二维码文件路径
	qrcodePath := filepath.Join(qq, "cache", "qrcode.png")

	var response struct {
		FileModTime string `json:"fileModTime"`
		FileExists  bool   `json:"fileExists"`
	}

	// 检查文件是否存在并获取修改时间
	if stat, err := os.Stat(qrcodePath); err == nil {
		response.FileModTime = stat.ModTime().Format("2006-01-02 15:04:05")
		response.FileExists = true
	} else {
		response.FileModTime = "文件不存在"
		response.FileExists = false
	}

	// 设置响应头
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")

	// 返回JSON响应
	if err := json.NewEncoder(w).Encode(response); err != nil {
		http.Error(w, "JSON编码错误", http.StatusInternalServerError)
		return
	}
}

// renderQRCodePage 渲染包含自动刷新功能的HTML页面
func renderQRCodePage(w http.ResponseWriter, qq string) {
	// 获取二维码文件的修改时间
	qrcodePath := filepath.Join(qq, "cache", "qrcode.png")
	var fileModTime string
	if stat, err := os.Stat(qrcodePath); err == nil {
		fileModTime = stat.ModTime().Format("2006-01-02 15:04:05")
	} else {
		fileModTime = "文件不存在"
	}

	htmlTemplate := `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扫码登录</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #f5f5f5;
            margin: 0;
            padding: 20px;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            background: white;
            border-radius: 10px;
            padding: 30px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            margin-bottom: 20px;
        }
        .qrcode-container {
            margin-top: 20px;
        }
        #qrcode {
            max-width: 100%;
            height: auto;
            border: 2px solid #ddd;
            border-radius: 8px;
        }
        .info {
            color: #666;
            margin: 4px 0;
            font-size: 14px;
        }
        .status {
            margin: 4px 0;
            padding: 10px;
            border-radius: 5px;
            background-color: #e8f5e8;
            color: #2d5a2d;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>扫码登录</h1>
        <div class="qrcode-container">
            <img id="qrcode" src="/{{.QQ}}/qrcode?t={{.Timestamp}}" alt="二维码" onerror="handleImageError()">
        </div>
        <div class="info">
            <p>请使用手机QQ扫描上方二维码进行登录</p>
        </div>
        <div class="status">
            <p>当前登录QQ: {{.QQ}}</p>
            <p>上次更新时间: <span id="lastUpdate">{{.FileModTime}}</span></p>
        </div>
    </div>

    <script>
        let refreshInterval;
        
        function updateQRCode() {
            const img = document.getElementById('qrcode');
            const timestamp = new Date().getTime();
            const newSrc = '/{{.QQ}}/qrcode?t=' + timestamp;
            
            // 获取文件修改时间
            fetch('/{{.QQ}}/qrcode/info')
                .then(response => response.json())
                .then(data => {
                    if (data.fileModTime) {
                        document.getElementById('lastUpdate').textContent = data.fileModTime;
                    }
                })
                .catch(error => {
                    console.log('获取文件信息失败:', error);
                });
            
            // 创建新的图片对象来预加载
            const newImg = new Image();
            newImg.onload = function() {
                img.src = newSrc;
            };
            newImg.onerror = function() {
                console.log('二维码加载失败，将在下次刷新时重试');
            };
            newImg.src = newSrc;
        }
        
        function handleImageError() {
            console.log('二维码图片加载失败');
            document.getElementById('qrcode').alt = '二维码加载失败，请稍后刷新';
        }
        
        // 每5秒刷新一次二维码
        refreshInterval = setInterval(updateQRCode, 5000);
        
        // 页面可见性变化时的处理
        document.addEventListener('visibilitychange', function() {
            if (document.hidden) {
                clearInterval(refreshInterval);
            } else {
                updateQRCode();
                refreshInterval = setInterval(updateQRCode, 5000);
            }
        });
    </script>
</body>
</html>`

	tmpl, err := template.New("qrcode").Parse(htmlTemplate)
	if err != nil {
		http.Error(w, "模板解析错误", http.StatusInternalServerError)
		return
	}

	data := struct {
		QQ          string
		Timestamp   int64
		FileModTime string
	}{
		QQ:          qq,
		Timestamp:   time.Now().Unix(),
		FileModTime: fileModTime,
	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if err := tmpl.Execute(w, data); err != nil {
		http.Error(w, "模板执行错误", http.StatusInternalServerError)
		return
	}
}

// QRCodeImageHandler 专门处理二维码图片请求
func QRCodeImageHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	qq := vars["qq"]

	if qq == "" {
		http.Error(w, "QQ号不能为空", http.StatusBadRequest)
		return
	}

	// 构建二维码文件路径
	qrcodePath := filepath.Join(qq, "cache", "qrcode.png")

	// 检查文件是否存在
	if _, err := os.Stat(qrcodePath); os.IsNotExist(err) {
		http.Error(w, "二维码不存在", http.StatusNotFound)
		return
	}

	// 设置缓存控制头，防止浏览器缓存
	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	w.Header().Set("Pragma", "no-cache")
	w.Header().Set("Expires", "0")
	w.Header().Set("Content-Type", "image/png")

	// 返回图片文件
	http.ServeFile(w, r, qrcodePath)
}

func main() {
	// 定义命令行参数
	port := flag.Int("p", 8081, "指定服务器端口")
	flag.Parse()

	r := mux.NewRouter()

	// 主要的二维码页面路由
	r.HandleFunc("/{qq}/qrcode", QRCodeHandler).Methods("GET")

	// 二维码文件信息API路由
	r.HandleFunc("/{qq}/qrcode/info", QRCodeInfoHandler).Methods("GET")

	// 专门的二维码图片路由（用于AJAX请求）
	r.HandleFunc("/{qq}/qrcode", QRCodeImageHandler).Methods("GET").Headers("Accept", "image/png")

	// 启动服务器
	fmt.Println("NapCat QR Code Server 启动中...")
	fmt.Printf("服务器运行在: http://0.0.0.0:%d\n", *port)
	fmt.Printf("本地访问: http://localhost:%d/{QQ号}/qrcode\n", *port)
	fmt.Printf("外部访问: http://{服务器IP}:%d/{QQ号}/qrcode\n", *port)

	log.Fatal(http.ListenAndServe("0.0.0.0:"+strconv.Itoa(*port), r))
}